package com.gexiaobao.pigeon.ui.activity

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import androidx.camera.core.Camera
import androidx.camera.core.CameraControl
import androidx.camera.core.CameraInfo
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.Preview
import androidx.camera.core.VideoCapture
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
//import com.arthenica.ffmpegkit.FFmpegKit
//import com.arthenica.ffmpegkit.ReturnCode
import com.gexiaobao.pigeon.R
import com.gexiaobao.pigeon.app.base.BaseActivity
import com.gexiaobao.pigeon.app.ext.showMessage
import com.gexiaobao.pigeon.app.util.RxToast
import com.gexiaobao.pigeon.app.util.StatusBarUtil
import com.gexiaobao.pigeon.app.util.VideoMerger
import com.gexiaobao.pigeon.databinding.ActivityVideoCaptureBinding
import com.gexiaobao.pigeon.permissions.PermissionInterceptor
import com.gexiaobao.pigeon.ui.dialog.RxDialogDefault
import com.gexiaobao.pigeon.ui.view.RecordProgressView.OnRecordStatusListener
import com.gexiaobao.pigeon.viewmodel.MainViewModel
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import me.hgj.jetpackmvvm.ext.util.setOnclickNoRepeat
import me.hgj.jetpackmvvm.util.LogUtils
import me.hgj.jetpackmvvm.util.finish
import java.io.File
import java.util.stream.Collectors
import kotlin.math.max
import kotlin.math.min


/**
 * @Author      : hxw
 * @Date        : 2025/1/20 16:32
 * @Describe    :
 */
class VideoCaptureActivity : BaseActivity<MainViewModel, ActivityVideoCaptureBinding>() {

    private var imageCapture: ImageCapture? = null
    private var isFlashlightOn = false
    private lateinit var cameraProvider: ProcessCameraProvider
    private lateinit var camera: Camera
    private var isPermission = false

    @SuppressLint("RestrictedApi")
    private lateinit var videoCapture: VideoCapture
    private lateinit var cameraSelector: CameraSelector
    private var cameraControl: CameraControl? = null
    private var isRecording = false
    private var currentVideoFile: File? = null
    private var fileVideoList: ArrayList<String> = arrayListOf()

    private var timerJob: Job? = null
    private var seconds = 0

    private lateinit var scaleGestureDetector: ScaleGestureDetector

    @SuppressLint("RestrictedApi")
    override fun initView(savedInstanceState: Bundle?) {
        StatusBarUtil.setTranslucentForImageView(this, 0, null)
        requestPermission()

        // 初始化 ScaleGestureDetector
        scaleGestureDetector = ScaleGestureDetector(this, object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
            override fun onScale(detector: ScaleGestureDetector): Boolean {
                val scaleFactor = detector.scaleFactor
                adjustZoom(scaleFactor)
                return true
            }
        })
        // 默认选择后置摄像头
//        cameraSelector = CameraSelector.Builder()
//            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
//            .build()

        // 如果设备支持超广角镜头，则可以选择它(默认选择前置摄像头)
        cameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .addCameraFilter { cameras ->
                cameras.stream()
                    .filter { cameraInfo: CameraInfo -> cameraInfo.hasFlashUnit() } // 或者根据你的需求筛选
                    .collect(Collectors.toList())
            }.build()

        // 获取 CameraProvider 实例
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            cameraProvider = cameraProviderFuture.get()
            val preview = Preview.Builder().build().also {
                it.setSurfaceProvider(mDatabind.previewView.surfaceProvider)
            }
            camera = cameraProvider.bindToLifecycle(
                this, cameraSelector, preview
            )
            cameraControl = camera.cameraControl
            bindCameraUseCases() // 在创建 CameraProvider 后，绑定摄像头和录制用例
        }, ContextCompat.getMainExecutor(this))

        mDatabind.recordButton.setOnRecordStatusListener(object : OnRecordStatusListener {
            override fun onRecording() {
                if (!isPermission) {
                    showMessage("权限不足，请收到到设置中开启权限")
                    return
                }
                startRecording()
                mDatabind.ivStartAndStopVideo.isVisible = true
                startTimer()
            }

            override fun onPause() {
                stopRecording()
                timerJob?.cancel()
                mDatabind.ivStartAndStopVideo.isVisible = false
                showCheckVideoDialog()
            }

            override fun onFinish() {}
        })
    }

    private fun showCheckVideoDialog() {
        val dialog = RxDialogDefault(this)
        dialog.setTitle("是否使用并保存视频")
        dialog.setSureListener {
            val outputPath = createSynthesisVideoFile()
            if (fileVideoList.size == 1) {
                intentToUpActivity(fileVideoList[0])
                dialog.dismiss()
                return@setSureListener
            }
//            mergeVideos(fileVideoList, outputPath.absolutePath)
            VideoMerger.mergeVideos(this, fileVideoList, outputPath.absolutePath) { path ->
                if (path != null) {
                    intentToUpActivity(path)
                }
            }
            dialog.dismiss()
        }
        dialog.setCancelListener {
            timerJob?.cancel()
            seconds = 0
            mDatabind.timerTextView.text = "00:00"
            dialog.dismiss()
        }
        dialog.setFullScreenWidth()
        dialog.show()
    }

    private fun requestPermission() {
        XXPermissions.with(this)
            .permission(Permission.RECORD_AUDIO)
            .permission(Permission.CAMERA)
            .permission(Permission.READ_MEDIA_IMAGES)
            .permission(Permission.READ_MEDIA_VIDEO)
            .permission(Permission.READ_MEDIA_AUDIO)
            .permission(Permission.WRITE_EXTERNAL_STORAGE)
            .interceptor(PermissionInterceptor())
            .request { _, allGranted ->
                if (allGranted) {
                    isPermission = true
                } else {
                    isPermission = false
                    RxToast.showToast("权限不足，请手动开启权限后重试")
                }
            }
    }

    override fun onBindViewClick() {
        super.onBindViewClick()
        setOnclickNoRepeat(
            mDatabind.switchCameraButton, mDatabind.ivBack, mDatabind.ivStartAndStopVideo, mDatabind.ivFlashLamp
        ) {
            when (it) {
                mDatabind.ivFlashLamp -> toggleFlash()
                mDatabind.ivStartAndStopVideo -> {
                    if (isRecording) {
                        stopRecording()
                        timerJob?.cancel()
                        mDatabind.ivStartAndStopVideo.setImageResource(R.mipmap.icon_start_visit_video)
                    } else {
                        startRecording()
                        startTimer()
                        mDatabind.ivStartAndStopVideo.setImageResource(R.mipmap.icon_stop_visit_video)
                    }
                }

                mDatabind.ivBack -> finish()
                mDatabind.switchCameraButton -> {
                    if (isRecording) {
                        // 如果正在录制，则先暂停录制，再切换摄像头
                        pauseRecording()
                        switchCamera()
                        resumeRecording()
                    } else {
                        switchCamera()
                    }
                }
            }
        }
    }

    private fun toggleFlash() {
        if (!isTorchAvailable(cameraProvider)) {
            RxToast.showToast("本设备不支持闪光灯")
            return
        }
        isFlashlightOn = !isFlashlightOn
        if (cameraProvider.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA)) {
            cameraControl?.enableTorch(isFlashlightOn)
        }
        if (isFlashlightOn) {
            mDatabind.ivFlashLamp.setImageResource(R.mipmap.icon_flash_lamp_open)
        } else {
            mDatabind.ivFlashLamp.setImageResource(R.mipmap.icon_flash_lamp_close)
        }
    }

    private fun isTorchAvailable(cameraProvider: ProcessCameraProvider): Boolean {
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
        return cameraProvider.hasCamera(cameraSelector)
    }

    @SuppressLint("DefaultLocale")
    private fun startTimer() {
        timerJob?.cancel() // 取消任何现有计时器
        timerJob = CoroutineScope(Dispatchers.Main).launch {
            while (isRecording) {
                delay(1000)  // 延迟 1 秒
                seconds++
                val minutes = seconds / 60
                val remainingSeconds = seconds % 60
                mDatabind.timerTextView.text = String.format("%02d:%02d", minutes, remainingSeconds)
            }
        }
    }

    // 绑定 CameraX 使用的组件
    @SuppressLint("RestrictedApi")
    private fun bindCameraUseCases() {
        // 创建 Preview 用例
        val preview = Preview.Builder().build()
        preview.setSurfaceProvider(mDatabind.previewView.surfaceProvider)
        // 创建 VideoCapture 用例
        videoCapture = VideoCapture.Builder().build()
        imageCapture = ImageCapture.Builder()
            .setFlashMode(if (isFlashlightOn) ImageCapture.FLASH_MODE_ON else ImageCapture.FLASH_MODE_OFF)
            .build()
        // 解绑之前的相机用例并绑定新的
        cameraProvider.unbindAll()
        cameraProvider.bindToLifecycle(this, cameraSelector, preview, videoCapture)
    }

    // 切换摄像头
    @SuppressLint("RestrictedApi")
    private fun switchCamera() {
        // 通过改变 lensFacing 切换前后摄像头
        val lensFacing = if (cameraSelector.lensFacing == CameraSelector.LENS_FACING_FRONT) {
            CameraSelector.LENS_FACING_BACK
        } else {
            CameraSelector.LENS_FACING_FRONT
        }
        // 更新 cameraSelector
        cameraSelector = CameraSelector.Builder()
            .requireLensFacing(lensFacing)
            .build()
        // 重新绑定相机用例，切换摄像头，但保持录制
        bindCameraUseCases()
    }

    // 开始录制
    @SuppressLint("RestrictedApi", "MissingPermission")
    private fun startRecording() {
        // 创建新的视频文件
        currentVideoFile = createNewVideoFile()
        fileVideoList.add(currentVideoFile!!.absolutePath)
        val outputOptions = VideoCapture.OutputFileOptions.Builder(currentVideoFile!!).build()
        videoCapture.startRecording(outputOptions, ContextCompat.getMainExecutor(this), object : VideoCapture.OnVideoSavedCallback {
            override fun onVideoSaved(outputFileResults: VideoCapture.OutputFileResults) {
                LogUtils.debugInfo("Video saved: ${outputFileResults.savedUri}")
            }

            override fun onError(videoCaptureError: Int, message: String, cause: Throwable?) {
                LogUtils.debugInfo("Recording error: $message,$cause")
            }
        })
        isRecording = true
    }

    private fun pauseRecording() {
        // 如果是 CameraX 版本支持暂停功能，可以在这里调用暂停方法
        // 注意：截至 CameraX 1.2.0，不直接支持暂停录制，所以这里只是简单地停止录制
        stopRecording()
    }

    private fun resumeRecording() {
        // 如果是 CameraX 版本支持暂停功能，可以在这里调用恢复方法
        // 注意：截至 CameraX 1.2.0，不直接支持暂停录制，所以这里只是简单地重新开始录制
        startRecording()
    }

    // 停止录制
    @SuppressLint("RestrictedApi")
    private fun stopRecording() {
        videoCapture.stopRecording()
        isRecording = false
    }

    /** 创建录制的视频文件的文件路径 */
    private fun createNewVideoFile(): File {
        val videoFolder = getExternalFilesDir(null)
        return File.createTempFile("VID_${System.currentTimeMillis()}", ".mp4", videoFolder)
    }

    /** 创建合并后的文件路径 */
    private fun createSynthesisVideoFile(): File {
        val videoFolder = getExternalFilesDir(null)
        return File.createTempFile("VISIT_VID_${System.currentTimeMillis()}", ".mp4", videoFolder)
    }

//    private fun mergeVideos(inputFiles: ArrayList<String>, outputFile: String) {
//        val fileList = File(this.filesDir, "filelist.txt")
//        try {
//            fileList.bufferedWriter().use { writer ->
//                inputFiles.forEach {
//                    writer.write("file '$it'\n")
//                }
//            }
//        } catch (e: IOException) {
//            e.printStackTrace()
//        }
//        val command = "-y -f concat -safe 0 -i ${fileList.absolutePath} -c:v copy -c:a copy $outputFile"
//        // 执行 FFmpeg 命令
//        FFmpegKit.executeAsync(command) { session ->
//            LogUtils.debugInfo("FFmpeg 输出：${session.output}")
//            // 检查执行结果
//            val returnCode = session.returnCode
//            if (ReturnCode.isSuccess(returnCode)) {
//                intentToUpActivity(outputFile)
//            } else {
//                LogUtils.debugInfo(("视频合成失败：${session.failStackTrace}"))
//            }
//        }
//    }

    private fun intentToUpActivity(outputFile: String) {
        val intent = Intent()
        intent.putExtra("videoFile", outputFile)
        finish(intent)
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        scaleGestureDetector.onTouchEvent(event)
        return super.onTouchEvent(event)
    }

    private fun adjustZoom(scaleFactor: Float) {
        val cameraInfo: CameraInfo = camera.cameraInfo
        var zoomRatio: Float = cameraInfo.zoomState.getValue()!!.zoomRatio
        // 更新缩放比例
        zoomRatio *= scaleFactor
        // 获取相机支持的最大和最小缩放比例
        val minZoom: Float = cameraInfo.zoomState.getValue()!!.minZoomRatio
        val maxZoom: Float = cameraInfo.zoomState.getValue()!!.maxZoomRatio
        // 限制缩放比例在有效范围内
        zoomRatio = max(minZoom.toDouble(), min(zoomRatio.toDouble(), maxZoom.toDouble())).toFloat()
        // 设置新的缩放比例
        camera.cameraControl.setZoomRatio(zoomRatio)
    }

    @SuppressLint("RestrictedApi")
    override fun onStop() {
        super.onStop()
        videoCapture.stopRecording()
        fileVideoList.clear()
        timerJob?.cancel()
    }
}